package com.example.cameraxdemo

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Size
import android.widget.Button
import android.widget.Toast
import androidx.camera.core.*
import androidx.camera.core.ImageCapture.OnImageCapturedCallback
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.LifecycleOwner
import java.io.File

private const val REQ_CAMERA = 101

class MainActivity : AppCompatActivity() {

    private lateinit var preview: Preview
    private lateinit var imageAnalysis: ImageAnalysis
    private lateinit var cameraProvider: ProcessCameraProvider

    private lateinit var takePic: Button
    private lateinit var toggleCamera: Button
    private lateinit var previewView: PreviewView
    private lateinit var imageCapture: ImageCapture
    private lateinit var savePath: String

    private var isBackCamera: Boolean = true

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        savePath = filesDir.absolutePath + System.currentTimeMillis() + ".jpg"
        takePic = findViewById(R.id.take_pic)
        takePic.setOnClickListener {
            val metadata = ImageCapture.Metadata()
            metadata.isReversedHorizontal = !isBackCamera
            val outputFileOption =
                ImageCapture.OutputFileOptions.Builder(File(savePath)).setMetadata(metadata).build()
            imageCapture?.takePicture(
                outputFileOption,
                ContextCompat.getMainExecutor(this as Context),
                object : ImageCapture.OnImageSavedCallback {
                    override fun onError(error: ImageCaptureException) {
                        Toast.makeText(this@MainActivity, "拍照出错啦", Toast.LENGTH_SHORT).show()
                    }

                    override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
                        Toast.makeText(
                            this@MainActivity,
                            outputFileResults.savedUri.toString(),
                            Toast.LENGTH_SHORT
                        ).show()
                        val intent = Intent(this@MainActivity, PreviewActivity::class.java)
                        intent.putExtra(PREVIEW_PATH, outputFileResults.savedUri.toString())
                        startActivity(intent)
                    }
                })
        }
        toggleCamera = findViewById(R.id.toggle_camera)
        toggleCamera.setOnClickListener {
            isBackCamera = !isBackCamera
            setupCamera()
        }
        previewView = findViewById(R.id.preview)
        preview = Preview.Builder().build()
        preview.setSurfaceProvider(previewView.surfaceProvider)

        checkPermission()
    }

    private fun checkPermission() {
        if (ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.CAMERA
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), REQ_CAMERA)
        } else {
            initCamera()
        }
    }

    private fun initCamera() {
        previewView.post {
            imageCapture =
                ImageCapture.Builder().setTargetRotation(previewView.display.rotation).build()
            imageAnalysis = ImageAnalysis.Builder()
                .setTargetResolution(Size(previewView.width, previewView.height))
                .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
                .build()

            val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
            cameraProviderFuture.addListener(Runnable {
                cameraProvider = cameraProviderFuture.get()
                setupCamera()
            }, ContextCompat.getMainExecutor(this))
        }
    }

    private fun setupCamera() {
        cameraProvider?.let {
            cameraProvider.unbindAll()
            val cameraSelector =
                CameraSelector.Builder()
                    .requireLensFacing(if (isBackCamera) CameraSelector.LENS_FACING_BACK else CameraSelector.LENS_FACING_FRONT)
                    .build()
            cameraProvider.bindToLifecycle(
                this as LifecycleOwner,
                cameraSelector,
                imageCapture,
                imageAnalysis,
                preview
            )
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQ_CAMERA) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                initCamera()
            }
        } else {
        }
    }
}